package com.smart.upms.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Sets;
import com.smart.core.starter.constant.CommonConstant;
import com.smart.core.starter.utils.CopyUtils;
import com.smart.core.starter.utils.TreeUtil;
import com.smart.upms.constant.CacheConstant;
import com.smart.upms.sys.entity.SysMenu;
import com.smart.upms.sys.mapper.SysMenuMapper;
import com.smart.upms.sys.mapper.SysRoleMapper;
import com.smart.upms.sys.param.SysMenuParam;
import com.smart.upms.sys.param.SysMenuQueryParam;
import com.smart.upms.sys.result.SysMenuResult;
import com.smart.upms.sys.result.SysMenuTreeResult;
import com.smart.upms.sys.result.SysRoleResult;
import com.smart.upms.sys.service.ISysMenuService;
import lombok.AllArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单权限 服务实现类
 * </p>
 *
 * @author guxiaobai
 * @since 2018-12-05
 */
@Service
@AllArgsConstructor
public class SysMenuServiceImpl implements ISysMenuService {

    private final SysMenuMapper mapper;

    private final SysRoleMapper sysRoleMapper;


    @Override
    public Boolean save(SysMenuParam param) {
        SysMenu entity = CopyUtils.copyObject(param, SysMenu.class);
        int insert = mapper.insert(entity);
        return insert > 0;
    }

    @Override
    @CacheEvict(value = CacheConstant.CacheMenu.ROLE_MENU_DETAILS, allEntries = true)
    public Boolean update(SysMenuParam param) {
        SysMenu entity = CopyUtils.copyObject(param, SysMenu.class);
        int update = mapper.updateById(entity);
        return update > 0;

    }

    @Override
    @CacheEvict(value = CacheConstant.CacheMenu.ROLE_MENU_DETAILS, allEntries = true)
    public Boolean delete(Long id) {
        int delete = mapper.deleteById(id);
        return delete > 0;
    }

    @Override
    public SysMenuResult get(Long id) {
        SysMenu entity = mapper.selectById(id);
        return CopyUtils.copyObject(entity, SysMenuResult.class);
    }

    @Override
    public List<SysMenuResult> list(SysMenuQueryParam param) {
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        List<SysMenu> entityList = mapper.selectList(queryWrapper);
        return CopyUtils.copyList(entityList, SysMenuResult.class);
    }

    @Override
    public Page<SysMenuResult> listPage(Page<SysMenuResult> page, SysMenuQueryParam param) {
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        Page<SysMenu> entityPage = new Page<>();
        entityPage.setSize(page.getSize());
        entityPage.setCurrent(page.getCurrent());
        entityPage.setAsc(page.ascs());
        entityPage.setDesc(page.descs());
        mapper.selectPage(entityPage, queryWrapper);
        Page<SysMenuResult> resultPage = CopyUtils.copyPage(entityPage, SysMenuResult.class);
        return resultPage;
    }

    @Override
    @Cacheable(value = CacheConstant.CacheMenu.ROLE_MENU_DETAILS, key = "#roleCode")
    public List<SysMenuResult> findByRoleCode(String roleCode) {
        return mapper.findByRoleCode(roleCode);
    }

    @Override
    public List<SysMenuTreeResult> userMenu(Long userId) {
        List<SysRoleResult> roleResults = sysRoleMapper.findRolesByUserId(userId);
        HashSet<SysMenuResult> sysMenuResults = Sets.newHashSet();
        roleResults.forEach(result -> sysMenuResults.addAll(mapper.findByRoleCode(result.getRoleCode())));

        List<SysMenuTreeResult> sysMenuTreeResults = sysMenuResults.stream().filter(result -> CommonConstant.MenuType.MENU == result.getType())
                .map(result -> CopyUtils.copyObject(result, SysMenuTreeResult.class))
                .sorted(Comparator.comparingInt(SysMenuTreeResult::getSort))
                .collect(Collectors.toList());
        return TreeUtil.bulid(sysMenuTreeResults, -1L);
    }

    @Override
    public List<SysMenuTreeResult> allTree() {
        List<SysMenu> sysMenus = mapper.selectList(null);
        List<SysMenuTreeResult> sysMenuTreeResults = sysMenus.stream().filter(result -> CommonConstant.MenuType.MENU == result.getType())
                .map(result -> CopyUtils.copyObject(result, SysMenuTreeResult.class))
                .sorted(Comparator.comparingInt(SysMenuTreeResult::getSort))
                .collect(Collectors.toList());
        return TreeUtil.bulid(sysMenuTreeResults, -1L);
    }


}
